package com.hhq.usercenter.filter;

import cn.hutool.core.util.StrUtil;
import com.hhq.common.util.HttpUtil;
import com.hhq.usercenter.config.WebProperties;
import com.hhq.usercenter.constants.LoginConstants;
import com.hhq.usercenter.domain.pojo.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * <p>Description: some description </p>
 *
 * @author : xiaodong.yang
 * @date : 2024/1/9 9:41
 */
@Slf4j
@Component
public class RedisTokenFilter extends OncePerRequestFilter {

    @Autowired
    private WebProperties webProperties;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 获取请求头中的token
        String token = request.getHeader(LoginConstants.TOKEN);
        // 如果token不为空
        if (StringUtils.isNotBlank(token)) {
            // 验证token是否有效
            // 如果验证通过
            String tokenKey = webProperties.getSession().getPrefix() + StrUtil.C_COLON + token;
            Object user = redisTemplate.opsForValue().get(tokenKey);
            if (null == user) {
                // 验证失败，返回错误信息
                HttpUtil.response(response, HttpServletResponse.SC_UNAUTHORIZED, "未登录");
            } else {
                UserInfo userInfo = (UserInfo) user;
                // 保存用户信息
                UsernamePasswordAuthenticationToken userPwdToken = new UsernamePasswordAuthenticationToken(userInfo, null, userInfo.getAuthorities());
                SecurityContextHolder.getContext().setAuthentication(userPwdToken);
                //自动延迟token时间
                redisTemplate.opsForValue().set(tokenKey, userInfo, webProperties.getSession().getExpireTime(), TimeUnit.MINUTES);
                // 放行
                filterChain.doFilter(request, response);
            }
        } else {
            // 如果token为空，检查请求路径是否在白名单中
            String requestURI = request.getRequestURI();
            // 如果在白名单中，放行
            if (ArrayUtils.contains(webProperties.getWhiteNames().toArray(), requestURI)) {
                filterChain.doFilter(request, response);
            } else {
                // 如果不在白名单中，返回错误信息
                HttpUtil.response(response, HttpServletResponse.SC_UNAUTHORIZED, "未登录");
            }
        }
    }
}
